package com.eudon.genius.api.core.parser.component;

import com.github.javaparser.ast.body.ClassOrInterfaceDeclaration;
import com.github.javaparser.ast.body.MethodDeclaration;
import com.github.javaparser.ast.body.Parameter;
import com.github.javaparser.ast.comments.JavadocComment;
import com.github.javaparser.javadoc.Javadoc;
import lombok.Getter;
import lombok.Setter;
import lombok.extern.slf4j.Slf4j;

import java.util.HashMap;
import java.util.Map;
import java.util.Optional;

/**
 * JavaDoc注释解析器
 * 负责解析类和方法的JavaDoc注释，提取描述信息
 *
 * @author eudon
 * @since 2025/9/25
 */
@Slf4j
public class JavaDocParser {

    /**
     * 解析类的JavaDoc注释
     *
     * @param classDeclaration 类声明
     * @return 类描述信息
     */
    public ClassDocInfo parseClassDoc(ClassOrInterfaceDeclaration classDeclaration) {
        ClassDocInfo docInfo = new ClassDocInfo();
        docInfo.setClassName(classDeclaration.getNameAsString());

        Optional<JavadocComment> javadocComment = classDeclaration.getJavadocComment();
        if (javadocComment.isPresent()) {
            Javadoc javadoc = javadocComment.get().parse();

            // 提取描述
            String description = javadoc.getDescription().toText().trim();
            docInfo.setDescription(description.isEmpty() ? classDeclaration.getNameAsString() : description);

            // 提取作者信息
            javadoc.getBlockTags().stream()
                    .filter(tag -> "author".equals(tag.getTagName()))
                    .findFirst()
                    .ifPresent(tag -> docInfo.setAuthor(tag.getContent().toText().trim()));


            javadoc.getBlockTags().stream()
                    .filter(tag -> "since".equals(tag.getTagName()))
                    .findFirst()
                    .ifPresent(tag -> docInfo.setSince(tag.getContent().toText().trim()));
            // 提取版本信息
            javadoc.getBlockTags().stream()
                    .filter(tag -> "version".equals(tag.getTagName()))
                    .findFirst()
                    .ifPresent(tag -> docInfo.setVersion(tag.getContent().toText().trim()));

        } else {
            // 没有JavaDoc注释时使用类名作为描述
            docInfo.setDescription(classDeclaration.getNameAsString());
        }

        return docInfo;
    }

    /**
     * 解析方法的JavaDoc注释
     *
     * @param methodDeclaration 方法声明
     * @return 方法描述信息
     */
    public MethodDocInfo parseMethodDoc(MethodDeclaration methodDeclaration) {
        MethodDocInfo docInfo = new MethodDocInfo();
        docInfo.setMethodName(methodDeclaration.getNameAsString());

        Optional<JavadocComment> javadocComment = methodDeclaration.getJavadocComment();
        if (javadocComment.isPresent()) {
            Javadoc javadoc = javadocComment.get().parse();

            // 提取方法描述
            String description = javadoc.getDescription().toText().trim();
            docInfo.setDescription(description.isEmpty() ? methodDeclaration.getNameAsString() : description);

            // 提取参数描述
            Map<String, String> paramDescriptions = new HashMap<>();
            javadoc.getBlockTags().stream()
                    .filter(tag -> "param".equals(tag.getTagName()))
                    .forEach(tag -> {
                        String content = tag.getContent().toText().trim();
                        String[] parts = content.split("\\s+", 2);
                        if (parts.length >= 2) {
                            paramDescriptions.put(parts[0], parts[1]);
                        } else if (parts.length == 1) {
                            paramDescriptions.put(parts[0], "");
                        }
                    });
            docInfo.setParameterDescriptions(paramDescriptions);

            // 提取返回值描述
            javadoc.getBlockTags().stream()
                    .filter(tag -> "return".equals(tag.getTagName()))
                    .findFirst()
                    .ifPresent(tag -> docInfo.setReturnDescription(tag.getContent().toText().trim()));

        } else {
            // 没有JavaDoc注释时使用方法名作为描述
            docInfo.setDescription(methodDeclaration.getNameAsString());
            docInfo.setParameterDescriptions(new HashMap<>());
        }

        return docInfo;
    }

    /**
     * 类文档信息
     */
    @Setter
    @Getter
    public static class ClassDocInfo {
        // Getters and Setters
        private String className;
        private String description;
        private String author;
        private String since;
        private String version;

    }

    /**
     * 方法文档信息
     */
    @Setter
    @Getter
    public static class MethodDocInfo {
        // Getters and Setters
        private String methodName;
        private String description;
        private Map<String, String> parameterDescriptions;
        private String returnDescription;

    }
}